#!/usr/bin/env python3
# coding=utf-8

import os
import argparse

def get_data_from_s19(line):
    ch0 = line[0]
    ch1 = line[1]
    if ch0 == 'S' and (ch1=='1' or ch1=='2' or ch1=='3'):
        '''
        S1/S2/S3: read data record.
        int(line[2]+line[3], 16) = addr + data + checksum.
        ord(line[1])-ord('0')+1  = S1/S2/S3: 2/3/4.
        1                        = checksum
        '''
        size = (int(line[2]+line[3], 16)-(ord(line[1])-ord('0')+1)-1)

        '''
        S31500011000E002E82A000000000000000000000000E5:

        4                         = S315
        (ord(line[1])-ord('0')+1) = 00011000
        '''
        index = (4+(ord(line[1])-ord('0')+1)*2)
        d = line[index:index+size*2]
        return d, size
    else:
        return None, None

def get_data_from(line, type):
    # print('line:', line)

    if type == 's19':
        return get_data_from_s19(line)

    # hex file.
    #
    ch0 = line[7]
    ch1 = line[8]
    if ch0 == '0' and ch1 == '0':
        size = int(line[1]+line[2], 16)
        # print('size:', size)
        d = line[9:(size*2+9)]
        # print('data:', d)

        return d, size
    else:
        return None, None

def get_data_from_bin(fpbin, size):
    data = fpbin.read(size)
    return data.hex()
    # return data

def compare(file, bin, type):
    '''

    1. open files.
    2. readline from hex file.
    3. get hex line bin data and size.
    4. read size of data from bin file.
    5. compare data, if failure exit with failure.
    6. loop to 1.

    '''
    fp_hex = open(file, 'r')
    fp_bin = open(bin, 'rb')

    ok = True
    total = 0
    compared = 0

    while True:
        line = fp_hex.readline()
        if line == '':
            # print('file end:', file)
            break

        bdata0, size = get_data_from(line, type)

        if size is not None:
            total += size

        if ok and (bdata0 is not None and size is not None):
            bdata1 = get_data_from_bin(fp_bin, size)

            if bdata0.upper() != bdata1.upper():
                print('line:', line)
                print('bdata0:', bdata0, size)
                print('bdata1:', bdata1)
                print(f'\033[1;31;47m{"error: compare failure."}\033[0m')
                ok = False
            else:
                compared += size
        
    fp_hex.close()
    fp_bin.close()

    statinfo = os.stat(bin)

    info = 'file: ' + file + ' total ' + str(total) + ' bytes, compared ' + str(compared) + ' bytes, bin ' + str(statinfo.st_size) + ' bytes.'

    if ok:
        print(f'\033[1;32;47m{info}\033[0m')
        print(f'\033[1;32;47m{"compare successfully."}\033[0m')
    else:
        print(f'\033[1;31;47m{info}\033[0m')


def compare_hex(hex, bin):
    compare(hex, bin, 'hex')

def compare_s19(s19, bin):
    compare(s19, bin, 's19')

if __name__=='__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--hex', type=str, default=None)
    parser.add_argument('--s19', type=str, default=None)
    parser.add_argument('--bin', type=str, default=None)
    args = parser.parse_args()

    '''

    ch0 = '1'
    ch1 = '0'

    i = int(ch0+ch1, 16)

    print('int: ', i)

    '''

    hex = args.hex
    s19 = args.s19
    bin = args.bin

    if hex is not None and bin is not None:
        compare_hex(hex, bin)
    elif s19 is not None and bin is not None:
        compare_s19(s19, bin)
    else:
        print('error invalid args:', hex, s19, bin)

